home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / go4gw1.1 / g2nntp < prev    next >
Encoding:
Text File  |  1993-04-30  |  7.2 KB  |  300 lines

  1. #!/usr/local/bin/perl
  2.  
  3. #----------------------------------------------------------------------
  4. # variables you might have to change:
  5.  
  6. $nntp_server = "news.cis.umn.edu";
  7. $nntp_port   = 119;
  8. $nntp_defart = "article";
  9. $nntp_groups = "/etc/go4gw/ACTIVE"; # could be active file
  10. $nntp_reverse = 0;  # to list articles in reverse order
  11.  
  12. #----------------------------------------------------------------------
  13.  
  14. @nntp_acl=(
  15. #     ipaddress  group    access + = allow, - = deny    
  16.      '^134.84\.  .*       +',
  17.      '^128.101\. .*       +',
  18.      '^131.212\. .*       +',
  19.      '^146.57\.  .*       +',
  20.      '.*         ^clari   -',
  21.      '.*         .*       +'
  22.   );
  23. # end of variables
  24.  
  25. # Commands this server responds to:
  26. # ""                         -> list top level groups
  27. # ls  [$group] [$range]      -> list group's articles and sub-groups
  28. # lsa [$group] [$range]      -> like "", sends "article" & "lsa" commands back
  29. # lsb [$group] [$range]      -> "" sends "body" & "lsb" commands back
  30. # lsh [$group] [$range]      -> "" sends "header" & "lsh" commands back
  31. # article <id>               -> get article by ID
  32. # article $group $number     -> get 1 article, number can be "last" or "first",
  33. #                               or any numeric perl expression.
  34. # body <id>                  -> like article, but just get text
  35. # body $group $number        -> ""
  36. # head <id>                  -> like article, but just get header
  37. # head $group $number        -> ""
  38. # sorry                      -> send sorry message
  39. #
  40. # The optional $range arguement has the following format:
  41. #      n         - return 'n' most recent articles
  42. #     x:y        - return articles x through y (inclusive)
  43. #                  x and y can both be numeric perl expressions. The
  44. #                  string 'last' is replaced with the last article in the
  45. #                  group, and the string 'first' is replaced with the first.
  46. #   first:last   - all articles (same as not specifiying a range
  47. #   last:first   - all articles (in reverse order)
  48. #  last-9:last   - return last 10 articles (same as specifiying 10)
  49. #  last:last-9   - return last 10 articles in reverse order
  50.  
  51.  
  52. sub nntp_main {
  53.   local($_) = @_;
  54.  
  55.   &do_ls("",$nntp_defart,"ls") if /^$/;
  56.   &do_ls("",$nntp_defart,"ls") if /^ls\s*$/;
  57.   &do_ls($1,$nntp_defart,"ls") if /^ls\s+(.*)/i;
  58.  
  59.   &do_ls("","article","lsa") if /^lsa\s*$/;
  60.   &do_ls($1,"article","lsa") if /^lsa\s+(.*)/i;
  61.  
  62.   &do_ls("","body","lsb") if /^lsb\s*$/;
  63.   &do_ls($1,"body","lsb") if /^lsb\s+(.*)/i;
  64.  
  65.   &do_ls("","head","lsh") if /^lsh\s*$/;
  66.   &do_ls($1,"head","lsh") if /^lsh\s+(.*)/i;
  67.  
  68.   &do_article($1,$2,"ARTICLE") if /^article\s+(\S+)\s+(\S+)/i;
  69.   &do_article_id($1,"ARTICLE") if /^article\s+(<.*>)/i;
  70.  
  71.   &do_article($1,$2,"HEAD") if /^head\s+(\S+)\s+(\S+)/i;
  72.   &do_article_id($1,"HEAD") if /^head\s+(<.*>)/i;
  73.  
  74.   &do_article($1,$2,"BODY") if /^body\s+(\S+)\s+(\S+)/i;
  75.   &do_article_id($1,"BODY") if /^body\s+(<.*>)/i;
  76.  
  77.   &Gsorry if /^sorry$/;
  78.   &Gabort("Unknown command!");
  79.   exit;
  80. }
  81.  
  82. sub do_article_id {
  83.   local($id,$cmd) = @_;
  84.   &open_nntp;
  85.   &Gsend("$cmd $id");
  86.   $_ = &Grecv;
  87.   &Gabort($_) if !/^2/;
  88.  
  89.   while(<GSERVER>) {
  90.     print;
  91.     last if /^\.\r\n$/;
  92.   }
  93.  
  94.   &close_nntp;
  95.   exit;
  96.  
  97. }
  98.  
  99. sub do_article {
  100.   local($group,$number,$cmd) = @_;
  101.  
  102.   if (&check_access($group) eq '-')  { &Gsorry; }
  103.   &open_nntp;
  104.  
  105.   &Gsend("GROUP $group");
  106.   $_ = &Grecv;
  107.   &Gabort($_) if !/^2/;
  108.   ($n,$f,$l) = /\d+\s+(\d+)\s+(\d+)\s+(\d+)/;
  109.  
  110.   $number =~ s/first/\$f/g;
  111.   $number =~ s/last/\$l/g;
  112.   $number = int(eval($number));
  113.  
  114.   &Gsend("$cmd $number");
  115.   $_ = &Grecv;
  116.   &Gabort($_) if !/^2/;
  117.  
  118.   while(<GSERVER>) {
  119.     print;
  120.     last if /^\.\r\n$/;
  121.   }
  122.  
  123.   &close_nntp;
  124.   exit;
  125. }
  126.  
  127. sub list_group {
  128.   local($group,$type,$range) = @_;
  129.  
  130.   &Gsend("GROUP $group");
  131.   $_ = &Grecv;
  132.   &Gabort($_) if !/^211/;
  133.  
  134.   ($n,$f,$l) = /211\s+(\d+)\s+(\d+)\s+(\d+)/;
  135.  
  136.   if ($range =~ /^(\S+):(\S+)$/) {
  137.       $low = $1; $high = $2;
  138.       $low =~ s/first/\$f/g;
  139.       $low =~ s/last/\$l/g;
  140.       $high =~ s/first/\$f/g;
  141.       $high =~ s/last/\$l/g;
  142.       $low  = int(eval($low));
  143.       $high = int(eval($high));
  144.       if ($low > $l) { $low = $l; }
  145.       elsif ($low < $f) {$low = $f; }
  146.       if ($high > $l) { $high = $l; }
  147.       elsif ($high < $f) {$high = $f; }
  148.  
  149.       if ($high < $low)  {  $f = $high; $l = $low;  $nntp_reverse=1; }
  150.       if ($low <= $high) {  $f = $low; $l = $high;  $nntp_reverse=0; }
  151.         
  152.   }
  153.   elsif ($range ne '') {
  154.        $range =~ s/first/\$f/g;
  155.        $range =~ s/last/\$l/g;
  156.        $range = int(eval($range));
  157.        if ($range >0 && $range < $n) {  $f = $l - $range + 1; }
  158.   }
  159.  
  160.   &Gsend("XHDR Subject $f-$l");
  161.   $_ = &Grecv;
  162.   &Gabort($_) if !/^221/;
  163.  
  164.   while(<GSERVER>) {
  165.     chop; chop;
  166.     last if /^\.$/;
  167.     ($article,$subject) = /^(\d+)\s+(.*)/;
  168.     $subject =~ s/\t/ /g; # just in case!
  169.     if ($nntp_reverse) {
  170.        push(@reply,"0$subject\t$Ggw $atype $group $article\t$Ghost\t$Gport");
  171.     } else {
  172.        &Greply("0$subject\t$Ggw $atype $group $article\t$Ghost\t$Gport");
  173.     }
  174.   }
  175.  
  176.   if ($nntp_reverse) {
  177.     for ($i=$#reply; $i!= -1; $i--) { &Greply($reply[$i]); } 
  178.   }
  179.  
  180.   &Greply(".");
  181.   &close_nntp;
  182.   exit;
  183. }
  184.  
  185. sub do_ls {
  186.   local($prefix,$atype,$lscmd) = @_;
  187.   local($range);
  188.  
  189.   $prefix =~ s/\s+$//;
  190.  
  191.   if ($prefix =~ /(\S+)\s+(\S+)/) {
  192.       $prefix = $1;
  193.       $range  = $2;
  194.   }
  195.   elsif (($prefix =~ /^\d+$/) || ($prefix =~ /:/)) {
  196.       $range = $prefix;
  197.       $prefix = "";
  198.   }
  199.  
  200.   if (&check_access($prefix) eq '-') {
  201.       &Greply("0Sorry! No access off of campus!\t$Ggw sorry\t$Ghost\t$Gport");
  202.       &Greply("."); 
  203.       exit; 
  204.   }
  205.  
  206.   &open_nntp;
  207.   &get_groups;
  208.  
  209.   foreach ( sort @groups) {
  210.     if ($_ eq $prefix) { $do_list_group = $_; }
  211.     elsif (/^$prefix\.([^.]*)\.?/) {
  212.       $leaf=$1;
  213.       $save{"$prefix.$leaf"} = "1$leaf\t$Ggw $lscmd $prefix.$leaf $range\t$Ghost\t$Gport";
  214.     }
  215.     elsif ($prefix eq '' && /([^.]*)/) {
  216.          $save{"$1"} = "1$1\t$Ggw $lscmd $1 $range\t$Ghost\t$Gport";
  217.     }
  218.   }
  219.  
  220.   foreach ( sort keys %save) { &Greply($save{$_}); }
  221.   &list_group($do_list_group,$atype,$range) if ($do_list_group);
  222.  
  223.   &Greply(".");
  224.   &close_nntp;
  225.   exit;
  226. }
  227.  
  228. sub open_nntp {
  229.   local($_);
  230.   &GopenServer($nntp_server,$nntp_port);
  231.   $_ = &Grecv;
  232.   &Gabort($_) if !/^2/;
  233. }
  234.  
  235. sub close_nntp {
  236.   &Gsend("QUIT");
  237.   close(GSERVER);
  238. }
  239.  
  240. sub get_groups {
  241.  if (open(GROUPS,$nntp_groups)) {
  242.       while(<GROUPS>) {
  243.           chop;
  244.           ($grp) = /^(\S+)/;
  245.           push(@groups,$grp);
  246.       }
  247.       close(GROUPS);
  248.  } else {                  # can't open file, get list from server!
  249.   &load_groups;
  250.  }
  251. }
  252.  
  253. sub load_groups {
  254.  
  255.   &open_nntp;
  256.   &Gsend("LIST");
  257.   $_ = &Grecv;
  258.   &Gabort($_) if !/^215/;
  259.  
  260.   while(<GSERVER>) {
  261.     chop; chop;
  262.     last if /^\.$/;
  263.     s/^(\S+).*/$1/;
  264.     push(@groups,$_);
  265.   }
  266.  
  267. }
  268.  
  269. sub create_groups { 
  270.   &load_groups;
  271.   open(GROUPS,">$nntp_groups") || die "$nntp_groups: $!";
  272.   foreach (@groups) { print GROUPS "$_\n"; }
  273.   close GROUPS;
  274.   &close_nntp;
  275.   exit;
  276. }
  277.  
  278. sub check_access {
  279.    local($group)=@_;
  280.  
  281.    return 1 if (-t STDIN);
  282.    $sockaddr = 'S n a4 x8';
  283.    $mysockaddr = getpeername(STDIN);
  284.    ($ramily,$rport,$raddr) = unpack($sockaddr,$mysockaddr);
  285.    ($a,$b,$c,$d) = unpack('C4',$raddr);
  286.    $ipaddress = "$a.$b.$c.$d";
  287.  
  288.    foreach (@nntp_acl) {
  289.       ($ipacl,$groupacl,$access)=split;
  290.       return $access if  ($ipaddress =~ /$ipacl/) && ($group =~ /$groupacl/);
  291.    }
  292.    return '-'; #default is to restrict access
  293. }
  294.  
  295. 1; # for require
  296.  
  297.  
  298.  
  299.